﻿using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.ObjectModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Drawing;

namespace VioletDevelopmentLaboratory.Net.Web.WebControls
{
	public enum PagerButtonMode { Link, PostBack }

	public delegate void PagerButton_PageIndexChanged(object sender, PagerButtonPageIndexChangedEventArgs e);
	public class PagerButtonPageIndexChangedEventArgs : EventArgs
	{
		private PagerButtonPageIndexChangedEventArgs() { }

		internal PagerButtonPageIndexChangedEventArgs(int newPageIndex, string newPageUrl)
		{
			this.NewPageIndex = newPageIndex;
			this.NewPageUrl = newPageUrl;
		}

		private int newPageIndex;
		public int NewPageIndex
		{
			get { return newPageIndex; }
			private set { newPageIndex = value; }
		}

		private string newPageUrl;
		public string NewPageUrl
		{
			get { return this.newPageUrl; }
			private set { this.newPageUrl = value; }
		}
	}

	public class CustomQueryStringParameter
	{
		public CustomQueryStringParameter() { }

		private string name;
		public string Name { get { return this.name; } set { this.name = value; } }

		private string defaultValue;
		public string DefaultValue { get { return this.defaultValue; } set { this.defaultValue = value; } }
	}

	[ToolboxData("<{0}:PagerButton runat=server></{0}:PagerButton>"),
	ParseChildren(true),
	Designer(typeof(VWebControlDesigner))]
	public class PagerButton : Control, INamingContainer
	{
		protected Panel parentPanel;

		public PagerButton()
		{
			this.PageSize = 10;
			this.ButtonCount = 0;
			this.SelectCount = 0;
			this.PageIndexQueryStringName = "";
			this.SelectedNumericButtonTextFormat = "";
			this.CssClass = "";
			this.SeparateText = "";
			this.NumericButtonCssClass = "";
			this.CurrentPageIndex = 0;
			this.Mode = PagerButtonMode.Link;
			this.customQueryStringParameters = new Collection<CustomQueryStringParameter>();

			this.FirstButton_Text = "";
			this.FirstButton_CssClass = "";
			this.FirstButton_OffImageUrl = "";
			this.FirstButton_OnImageUrl = "";

			this.PreviousButton_Text = "";
			this.PreviousButton_CssClass = "";
			this.PreviousButton_OffImageUrl = "";
			this.PreviousButton_OnImageUrl = "";

			this.NextButton_Text = "";
			this.NextButton_CssClass = "";
			this.NextButton_OffImageUrl = "";
			this.NextButton_OnImageUrl = "";

			this.LastButton_Text = "";
			this.LastButton_CssClass = "";
			this.LastButton_OffImageUrl = "";
			this.LastButton_OnImageUrl = "";
		}

		#region Event
		[Category("Action")]
		public event PagerButton_PageIndexChanged PageIndexChanged;

		protected override bool OnBubbleEvent(object sender, EventArgs args)
		{
			if (sender is IButtonControl)
			{
				IButtonControl commandbutton = (IButtonControl)sender;

				this.CurrentPageIndex = int.Parse(commandbutton.CommandArgument);

				PagerButtonPageIndexChangedEventArgs eventArgs = new PagerButtonPageIndexChangedEventArgs(this.CurrentPageIndex, this.createUrl(this.CurrentPageIndex));

				this.PageIndexChanged(this, eventArgs);

				CreatePageButtons();
			}

			return true;
		}
		#endregion

		#region Helper
		//주소
		private string createUrl(int pageIndex)
		{
			string url = HttpContext.Current.Request.Path + "?" + this.PageIndexQueryStringName + "=" + pageIndex;

			foreach (CustomQueryStringParameter query in this.customQueryStringParameters)
			{
				url = url + "&" + query.Name + "=" + (String.IsNullOrEmpty(query.DefaultValue) ? HttpContext.Current.Request.QueryString[query.Name] : query.DefaultValue);
			}
			return url;
		}

		//페이지
		private PlaceHolder createNumericLink(int pageIndex)
		{
			PlaceHolder li = new PlaceHolder();
			li.EnableViewState = false;

			if (this.CurrentPageIndex == pageIndex)
			{
				Literal num = new Literal();
				num.EnableViewState = false;
				num.Text = String.Format(this.SelectedNumericButtonTextFormat, pageIndex + 1);

				li.Controls.Add(num);
			}
			else
			{
				switch (Mode)
				{
					case PagerButtonMode.Link :
						Literal linkLiteral = new Literal();
						linkLiteral.Text = String.Format("<a href=\"{0}\">{1}</a>", createUrl(pageIndex).Replace("&", "&amp;"), pageIndex + 1);

						li.Controls.Add(linkLiteral);
						break;
					case PagerButtonMode.PostBack :
						LinkButton linkButton = new LinkButton();
						linkButton.Text = (pageIndex + 1).ToString();
						linkButton.CommandArgument = pageIndex.ToString();

						li.Controls.Add(linkButton);
						break;
				}
			}

			return li;
		}

		//처음,이전,다음,마지막
		private PlaceHolder createMoveLink(bool conditional, string buttonText, string onButtonImageUrl,
			string offButtonImageUrl, string buttonCssClass, int pageIndex)
		{
			PlaceHolder li = new PlaceHolder();
			li.EnableViewState = false;

			if (conditional)
			{
				switch (Mode)
				{
					case PagerButtonMode.Link :
						HyperLink link = new HyperLink();
						link.NavigateUrl = createUrl(pageIndex);
						link.Text = buttonText;
						link.ImageUrl = onButtonImageUrl;

						li.Controls.Add(link);
						break;
					case PagerButtonMode.PostBack :
						ImageButton imageButton = new ImageButton();
						imageButton.ImageUrl = onButtonImageUrl;
						imageButton.AlternateText = buttonText;
						imageButton.CommandArgument = pageIndex.ToString();

						li.Controls.Add(imageButton);
						break;
				}
			}
			else if (string.IsNullOrEmpty(offButtonImageUrl))
			{
				Literal label = new Literal();
				label.EnableViewState = false;
				label.Text = buttonText;
				li.Controls.Add(label);
			}
			else
			{
				System.Web.UI.WebControls.Image image = new System.Web.UI.WebControls.Image();
				image.EnableViewState = false;
				image.ImageUrl = offButtonImageUrl;
				image.ToolTip = buttonText;
				image.AlternateText = "Page Button";
				li.Controls.Add(image);
			}

			return li;
		}

		//구분
		private Literal createSeparate()
		{
			Literal li = new Literal();
			li.EnableViewState = false;

			li.Text = this.SeparateText;
			return li;
		}
		#endregion

		#region QueryStringParameters
		private Collection<CustomQueryStringParameter> customQueryStringParameters;
		[Browsable(false),
		PersistenceMode(PersistenceMode.InnerProperty)]
		public Collection<CustomQueryStringParameter> QueryStringParameters
		{
			get { return this.customQueryStringParameters; }
		}
		#endregion

		#region Behavior
		[Browsable(false),
		Category("Behavior")]
		public Int64 SelectCount
		{
			get { return (Int64)this.ViewState["SelectCount"]; }
			set { this.ViewState["SelectCount"] = value; }
		}
		[Browsable(true),
		Category("Behavior"),
		DefaultValue(10)]
		public int ButtonCount
		{
			get { return Convert.ToInt32(this.ViewState["ButtonCount"]); }
			set { this.ViewState["ButtonCount"] = value; }
		}
		[Browsable(true),
		Category("Behavior"),
		DefaultValue("")]
		public string PageIndexQueryStringName
		{
			get { return this.ViewState["PageIndexQueryStringName"].ToString(); }
			set { this.ViewState["PageIndexQueryStringName"] = value; }
		}

		[Browsable(true),
		Category("Behavior"),
		DefaultValue(10)]
		public int PageSize
		{
			get { return Convert.ToInt32(this.ViewState["PageSize"]); }
			set { this.ViewState["PageSize"] = value; }
		}

		[Browsable(true),
		Category("Behavior"),
		DefaultValue("{0}")]
		public string SelectedNumericButtonTextFormat
		{
			get { return this.ViewState["SelectedNumericButtonTextFormat"].ToString(); }
			set { this.ViewState["SelectedNumericButtonTextFormat"] = value; }
		}

		[Browsable(true),
		Category("Behavior"),
		DefaultValue("0")]
		public int CurrentPageIndex
		{
			get { return (int)this.ViewState["CurrentPageIndex"]; }
			private set { this.ViewState["CurrentPageIndex"] = value; }
		}

		[Browsable(true),
		Category("Behavior"),
		DefaultValue(PagerButtonMode.Link)]
		public PagerButtonMode Mode
		{
			get { return (PagerButtonMode)this.ViewState["Mode"]; }
			set { this.ViewState["Mode"] = value; }
		}
		#endregion

		#region ParentPanel Appearance
		[Browsable(true),
		Category("Appearance"),
		DefaultValue("")]
		public string CssClass
		{
			get { return this.ViewState["CssClass"].ToString(); }
			set { this.ViewState["CssClass"] = value; }
		}
		#endregion

		#region MoveButton Appearance
		[Browsable(true), Category("Appearance")]
		public String FirstButton_CssClass
		{
			get { return this.ViewState["FirstButton_CssClass"].ToString(); }
			set { this.ViewState["FirstButton_CssClass"] = value; }
		}
		[Browsable(true), Category("Appearance")]
		public String FirstButton_Text
		{
			get { return this.ViewState["FirstButton_Text"].ToString(); }
			set { this.ViewState["FirstButton_Text"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String FirstButton_OffImageUrl
		{
			get { return this.ViewState["FirstButton_OffImageUrl"].ToString(); }
			set { this.ViewState["FirstButton_OffImageUrl"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String FirstButton_OnImageUrl
		{
			get { return this.ViewState["FirstButton_OnImageUrl"].ToString(); }
			set { this.ViewState["FirstButton_OnImageUrl"] = value; }
		}

		[Browsable(true), Category("Appearance")]
		public String PreviousButton_CssClass
		{
			get { return this.ViewState["PreviousButton_CssClass"].ToString(); }
			set { this.ViewState["PreviousButton_CssClass"] = value; }
		}
		[Browsable(true), Category("Appearance")]
		public String PreviousButton_Text
		{
			get { return this.ViewState["PreviousButton_Text"].ToString(); }
			set { this.ViewState["PreviousButton_Text"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String PreviousButton_OffImageUrl
		{
			get { return this.ViewState["PreviousButton_OffImageUrl"].ToString(); }
			set { this.ViewState["PreviousButton_OffImageUrl"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String PreviousButton_OnImageUrl
		{
			get { return this.ViewState["PreviousButton_OnImageUrl"].ToString(); }
			set { this.ViewState["PreviousButton_OnImageUrl"] = value; }
		}

		[Browsable(true), Category("Appearance")]
		public String NextButton_CssClass
		{
			get { return this.ViewState["NextButton_CssClass"].ToString(); }
			set { this.ViewState["NextButton_CssClass"] = value; }
		}
		[Browsable(true), Category("Appearance")]
		public String NextButton_Text
		{
			get { return this.ViewState["NextButton_Text"].ToString(); }
			set { this.ViewState["NextButton_Text"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String NextButton_OffImageUrl
		{
			get { return this.ViewState["NextButton_OffImageUrl"].ToString(); }
			set { this.ViewState["NextButton_OffImageUrl"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String NextButton_OnImageUrl
		{
			get { return this.ViewState["NextButton_OnImageUrl"].ToString(); }
			set { this.ViewState["NextButton_OnImageUrl"] = value; }
		}

		[Browsable(true), Category("Appearance")]
		public String LastButton_CssClass
		{
			get { return this.ViewState["LastButton_CssClass"].ToString(); }
			set { this.ViewState["LastButton_CssClass"] = value; }
		}
		[Browsable(true), Category("Appearance")]
		public String LastButton_Text
		{
			get { return this.ViewState["LastButton_Text"].ToString(); }
			set { this.ViewState["LastButton_Text"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String LastButton_OffImageUrl
		{
			get { return this.ViewState["LastButton_OffImageUrl"].ToString(); }
			set { this.ViewState["LastButton_OffImageUrl"] = value; }
		}
		[Browsable(true), Category("Appearance"),
		Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public String LastButton_OnImageUrl
		{
			get { return this.ViewState["LastButton_OnImageUrl"].ToString(); }
			set { this.ViewState["LastButton_OnImageUrl"] = value; }
		}
		#endregion

		#region NumericButton Appearance
		[Browsable(true),
		Category("Appearance"),
		DefaultValue("")]
		public string NumericButtonCssClass
		{
			get { return this.ViewState["NextButtonCssClass"].ToString(); }
			set { this.ViewState["NextButtonCssClass"] = value; }
		}
		#endregion

		#region Separate Appearance
		[Browsable(true),
		Category("Appearance"),
		DefaultValue("&nbsp;")]
		public string SeparateText
		{
			get { return this.ViewState["SeparateText"].ToString(); }
			set { this.ViewState["SeparateText"] = value; }
		}
		#endregion

		public void CreatePageButtons()
		{
			if (HttpContext.Current.Request.QueryString[this.PageIndexQueryStringName] != null)
				this.CurrentPageIndex = int.Parse(HttpContext.Current.Request.QueryString[this.PageIndexQueryStringName]);

			this.Controls.Clear();

			this.parentPanel = new Panel();
			this.parentPanel.EnableViewState = false;
			this.parentPanel.CssClass = this.CssClass;

			Int32 startNum = (this.CurrentPageIndex / this.ButtonCount) * this.ButtonCount;
			Int64 totalThread = this.SelectCount;
			Int32 totalPage = Convert.ToInt32((totalThread / this.PageSize) + 1);
			Int32 prePage = startNum - this.ButtonCount;
			Int32 nextPage = startNum + this.ButtonCount;

			if ((totalThread % this.PageSize) == 0)
				totalPage--;

			this.parentPanel.Controls.Add(this.createMoveLink(this.CurrentPageIndex != 0, this.FirstButton_Text, this.FirstButton_OnImageUrl, this.FirstButton_OffImageUrl, this.FirstButton_CssClass, 0));
			this.parentPanel.Controls.Add(this.createSeparate());
			this.parentPanel.Controls.Add(this.createMoveLink(startNum > 0, this.PreviousButton_Text, this.PreviousButton_OnImageUrl, this.PreviousButton_OffImageUrl, this.PreviousButton_CssClass, prePage));
			this.parentPanel.Controls.Add(this.createSeparate());

			if ((totalPage - startNum) < this.ButtonCount)
				startNum = totalPage - this.ButtonCount;

			for (int i = startNum; i < (startNum + this.ButtonCount); i++)
			{
				if ((i < totalPage) && (i >= 0))
				{
					this.parentPanel.Controls.Add(this.createNumericLink(i));
					this.parentPanel.Controls.Add(this.createSeparate());
				}
			}

			this.parentPanel.Controls.Add(this.createMoveLink((startNum + this.ButtonCount) < totalPage, this.NextButton_Text, this.NextButton_OnImageUrl, this.NextButton_OffImageUrl, this.NextButton_CssClass, nextPage));
			this.parentPanel.Controls.Add(this.createSeparate());
			this.parentPanel.Controls.Add(this.createMoveLink(this.CurrentPageIndex < (totalPage - 1), this.LastButton_Text, this.LastButton_OnImageUrl, this.LastButton_OffImageUrl, this.LastButton_CssClass, totalPage - 1));

			HtmlGenericControl div = new HtmlGenericControl("div");
			div.Style.Add("clear", "both");

			this.parentPanel.Controls.Add(div);

			this.Controls.Add(this.parentPanel);
		}

		protected override void CreateChildControls()
		{
			this.ButtonCount = VUtility.GetControlSetting(3, 20, this.ButtonCount, "PagerButton.ButtonCount", 10);
			this.SelectedNumericButtonTextFormat = VUtility.GetControlSetting(this.SelectedNumericButtonTextFormat, "PagerButton.SelectedNumericButtonTextFormat", "{0}");
			this.CssClass = VUtility.GetControlSetting(this.CssClass, "PagerButton.CssClass", "");
			this.SeparateText = VUtility.GetControlSetting(this.SeparateText, "PagerButton.SeparateText", "&nbsp;");
			this.NumericButtonCssClass = VUtility.GetControlSetting(this.NumericButtonCssClass, "PagerButton.NumericButtonCssClass", "");

			this.FirstButton_Text = VUtility.GetControlSetting(this.FirstButton_Text, "PagerButton.FirstButton_Text", "[First]");
			this.FirstButton_CssClass = VUtility.GetControlSetting(this.FirstButton_CssClass, "PagerButton.FirstButton_CssClass", "");
			this.FirstButton_OffImageUrl = VUtility.GetControlSetting(this.FirstButton_OffImageUrl, "PagerButton.FirstButton_OffImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.firstoffbutton.gif"));
			this.FirstButton_OnImageUrl = VUtility.GetControlSetting(this.FirstButton_OnImageUrl, "PagerButton.FirstButton_OnImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.firstonbutton.gif"));

			this.PreviousButton_Text = VUtility.GetControlSetting(this.PreviousButton_Text, "PagerButton.PreviousButton_Text", "[Previous]"); ;
			this.PreviousButton_CssClass = VUtility.GetControlSetting(this.PreviousButton_CssClass, "PagerButton.PreviousButton_CssClass", ""); ;
			this.PreviousButton_OffImageUrl = VUtility.GetControlSetting(this.PreviousButton_OffImageUrl, "PagerButton.PreviousButton_OffImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.preoffbutton.gif"));
			this.PreviousButton_OnImageUrl = VUtility.GetControlSetting(this.PreviousButton_OnImageUrl, "PagerButton.PreviousButton_OnImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.preonbutton.gif"));

			this.NextButton_Text = VUtility.GetControlSetting(this.NextButton_Text, "PagerButton.NextButton_Text", "[Next]");
			this.NextButton_CssClass = VUtility.GetControlSetting(this.NextButton_CssClass, "PagerButton.NextButton_CssClass", "");
			this.NextButton_OffImageUrl = VUtility.GetControlSetting(this.NextButton_OffImageUrl, "PagerButton.NextButton_OffImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.nextoffbutton.gif"));
			this.NextButton_OnImageUrl = VUtility.GetControlSetting(this.NextButton_OnImageUrl, "PagerButton.NextButton_OnImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.nextonbutton.gif"));

			this.LastButton_Text = VUtility.GetControlSetting(this.LastButton_Text, "PagerButton.LastButton_Text", "[Last]");
			this.LastButton_CssClass = VUtility.GetControlSetting(this.LastButton_CssClass, "PagerButton.LastButton_CssClass", "");
			this.LastButton_OffImageUrl = VUtility.GetControlSetting(this.LastButton_OffImageUrl, "PagerButton.LastButton_OffImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.lastoffbutton.gif"));
			this.LastButton_OnImageUrl = VUtility.GetControlSetting(this.LastButton_OnImageUrl, "PagerButton.LastButton_OnImageUrl",
				Page.ClientScript.GetWebResourceUrl(this.GetType(), "VioletDevelopmentLaboratory.Net.Web.WebResources.lastonbutton.gif"));

			this.CreatePageButtons();
		}
	}
}
